<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>Freetype OpenGL: demo-display-list.c</title>

<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="style.css" rel="stylesheet" type="text/css" />



</head>
<body>
<div id="content"><!-- do not remove this div! -->

<div id="top"><!-- do not remove this div! -->

  
  <div id="titlearea">
    
    <div id="projectname">Freetype OpenGL</div>
    
    
    <div id="projectbrief">A high quality OpenGL text rendering engine for C</div>
    
  </div>
  

<!--

<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  
  
  <td style="padding-left: 0.5em;">
   <div id="projectname">Freetype OpenGL
   &#160;<span id="projectnumber">0.1</span>
   </div>
   <div id="projectbrief">A high quality OpenGL text rendering engine for C</div>
  </td>
  
  
  
   
  
 </tr>
 </tbody>
</table>
</div>
-->


<!-- Generated by Doxygen 1.8.0 -->
<script type="text/javascript" src="dynsections.js"></script>
</div>
<div class="header">
  <div class="headertitle">
<div class="title">demo-display-list.c</div>  </div>
</div><!--header-->
<div class="contents">
<div class="fragment"><pre class="fragment"><span class="comment">/* =========================================================================</span>
<span class="comment"> * Freetype GL - A C OpenGL Freetype engine</span>
<span class="comment"> * Platform:    Any</span>
<span class="comment"> * WWW:         http://code.google.com/p/freetype-gl/</span>
<span class="comment"> * -------------------------------------------------------------------------</span>
<span class="comment"> * Copyright 2011,2012 Nicolas P. Rougier. All rights reserved.</span>
<span class="comment"> *</span>
<span class="comment"> * Redistribution and use in source and binary forms, with or without</span>
<span class="comment"> * modification, are permitted provided that the following conditions are met:</span>
<span class="comment"> *</span>
<span class="comment"> *  1. Redistributions of source code must retain the above copyright notice,</span>
<span class="comment"> *     this list of conditions and the following disclaimer.</span>
<span class="comment"> *</span>
<span class="comment"> *  2. Redistributions in binary form must reproduce the above copyright</span>
<span class="comment"> *     notice, this list of conditions and the following disclaimer in the</span>
<span class="comment"> *     documentation and/or other materials provided with the distribution.</span>
<span class="comment"> *</span>
<span class="comment"> * THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER &#39;&#39;AS IS&#39;&#39; AND ANY EXPRESS OR</span>
<span class="comment"> * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF</span>
<span class="comment"> * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO</span>
<span class="comment"> * EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,</span>
<span class="comment"> * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES</span>
<span class="comment"> * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;</span>
<span class="comment"> * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND</span>
<span class="comment"> * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT</span>
<span class="comment"> * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF</span>
<span class="comment"> * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span>
<span class="comment"> *</span>
<span class="comment"> * The views and conclusions contained in the software and documentation are</span>
<span class="comment"> * those of the authors and should not be interpreted as representing official</span>
<span class="comment"> * policies, either expressed or implied, of Nicolas P. Rougier.</span>
<span class="comment"> * =========================================================================</span>
<span class="comment"> *</span>
<span class="comment"> * Example usage with display lists</span>
<span class="comment"> *</span>
<span class="comment"> * ========================================================================= */</span>
<span class="preprocessor">#include &quot;freetype-gl.h&quot;</span>


<span class="comment">// ------------------------------------------------------- global variables ---</span>
<a name="_a0"></a><a class="code" href="structvector__t.html" title="Generic vector structure.">vector_t</a> * fonts;
<a name="_a1"></a><a class="code" href="structtexture__atlas__t.html" title="A texture atlas is used to pack several small regions into a single texture.">texture_atlas_t</a> *atlas;
<span class="keywordtype">char</span> *filename = <span class="stringliteral">&quot;./Vera.ttf&quot;</span>;
<span class="keywordtype">wchar_t</span> *text = L<span class="stringliteral">&quot;A Quick Brown Fox Jumps Over The Lazy Dog 0123456789&quot;</span>;



<span class="comment">// --------------------------------------------------------------- gl_print ---</span>
<span class="keywordtype">void</span> gl_print( <a name="_a2"></a><a class="code" href="structtexture__font__t.html" title="Texture font structure.">texture_font_t</a> * font,
               <span class="keywordtype">wchar_t</span> * text )
{
    <span class="keywordtype">size_t</span> i;
    <a name="_a3"></a><a class="code" href="structtexture__glyph__t.html" title="A structure that describe a glyph.">texture_glyph_t</a> * glyph = 0;
    <a class="code" href="structtexture__atlas__t.html" title="A texture atlas is used to pack several small regions into a single texture.">texture_atlas_t</a> * atlas = font-&gt;<a name="a4"></a><a class="code" href="structtexture__font__t.html#a7af3cbcbd3ac09b0765ca1afd6310ac5" title="Atlas structure to store glyphs data.">atlas</a>;

    glEnable( GL_TEXTURE_2D );
    glBindTexture( GL_TEXTURE_2D, atlas-&gt;<a name="a5"></a><a class="code" href="structtexture__atlas__t.html#a03e72bd01b6e5e97c0cc032d22c11c45" title="Texture identity (OpenGL)">id</a> );
    glEnable( GL_BLEND );

    <span class="comment">// For ALPHA texture (atlas depth = 1)</span>
    <span class="keywordflow">if</span>( atlas-&gt;<a name="a6"></a><a class="code" href="structtexture__atlas__t.html#a099b3a476240070bc06248218c9e230c" title="Depth (in bytes) of the underlying texture.">depth</a> == 1 )
    {
        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
        glColor4f( 0, 0, 0, 1 );  <span class="comment">// Actual font color</span>
    }
    <span class="comment">// For RGB texture (atlas depth = 3)</span>
    <span class="keywordflow">else</span> <span class="keywordflow">if</span>( atlas-&gt;<a class="code" href="structtexture__atlas__t.html#a099b3a476240070bc06248218c9e230c" title="Depth (in bytes) of the underlying texture.">depth</a> == 3 )
    {
        glEnable( GL_COLOR_MATERIAL );
        glBlendFunc( GL_CONSTANT_COLOR_EXT, GL_ONE_MINUS_SRC_COLOR );
        glColor4f( 1, 1, 1, 1 );
        glBlendColor( 0, 0, 0, 1 );
    }

    glPushMatrix();
    <span class="keywordflow">for</span>( i=0; i&lt;wcslen(text); ++i)
    {
        glyph = (<a class="code" href="structtexture__glyph__t.html" title="A structure that describe a glyph.">texture_glyph_t</a> *) <a name="a7"></a><a class="code" href="group__texture-font.html#ga06e988448ef6e118aa6e273df5892937" title="Request a new glyph from the font.">texture_font_get_glyph</a>( font, text[i] );
        <span class="keywordflow">if</span>( i &gt; 0 )
        {
            glTranslatef(0, <a name="a8"></a><a class="code" href="group__texture-font.html#ga77d1adb569e7eaa4aaf776dc28415c66" title="Get the kerning between two horizontal glyphs.">texture_glyph_get_kerning</a>( glyph, text[i-1] ), 0);
        }
        glCallList( glyph-&gt;<a name="a9"></a><a class="code" href="structtexture__glyph__t.html#ade972fbd816ec6f4dbd95ddd2e03746a" title="Glyph id (used for display lists)">id</a> );
        glTranslatef( (<span class="keywordtype">int</span>)glyph-&gt;<a name="a10"></a><a class="code" href="structtexture__glyph__t.html#aba3ece1130e9d96562a5c2ec3e60da4c" title="For horizontal text layouts, this is the horizontal distance (in fractional pixels) used to increment...">advance_x</a>, 0, 0 );
    }
    glPopMatrix();
}


<span class="comment">// ------------------------------------------------------------ gl_print_at ---</span>
<span class="keywordtype">void</span> gl_print_at( <a class="code" href="structtexture__font__t.html" title="Texture font structure.">texture_font_t</a> * font,
                  <span class="keywordtype">int</span> x, <span class="keywordtype">int</span> y, <span class="keywordtype">wchar_t</span> * text )
{
    glPushMatrix();  
    glTranslatef(x, y-(<span class="keywordtype">int</span>)font-&gt;<a name="a11"></a><a class="code" href="structtexture__font__t.html#a8bd92ddb4c8e456aac6a21f6c268b360" title="This field is simply used to compute a default line spacing (i.e., the baseline-to-baseline distance)...">height</a>, 0);
    gl_print( font, text );
    glPopMatrix();
}


<span class="comment">// ---------------------------------------------------------------- display ---</span>
<span class="keywordtype">void</span> display( <span class="keywordtype">void</span> )
{
    <span class="keywordtype">size_t</span> i;
    GLint viewport[4];
    glGetIntegerv( GL_VIEWPORT, viewport );

    glClearColor(1,1,1,1);
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glPushMatrix();
    glTranslatef(5, viewport[3], 0);
    <span class="keywordflow">for</span>( i=0; i&lt;<a name="a12"></a><a class="code" href="group__vector.html#ga0103842074bb797fc685b33c0629c05a" title="Returns the number of items.">vector_size</a>(fonts); ++i)
    {
        <a class="code" href="structtexture__font__t.html" title="Texture font structure.">texture_font_t</a> * font = (<a class="code" href="structtexture__font__t.html" title="Texture font structure.">texture_font_t</a> *) <a name="a13"></a><a class="code" href="group__vector.html#ga6ed3fefa82526009ff0763191dcd9a93" title="Returns a pointer to the item located at specified index.">vector_get</a>(fonts, i);
        glTranslatef(0, -(<span class="keywordtype">int</span>)font-&gt;<a class="code" href="structtexture__font__t.html#a8bd92ddb4c8e456aac6a21f6c268b360" title="This field is simply used to compute a default line spacing (i.e., the baseline-to-baseline distance)...">height</a>, 0);
        gl_print( font, text );
    }
    glPopMatrix();
    glutSwapBuffers( );
}

<span class="comment">// ---------------------------------------------------------------- reshape ---</span>
<span class="keywordtype">void</span> reshape(<span class="keywordtype">int</span> width, <span class="keywordtype">int</span> height)
{
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, width, 0, height, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glutPostRedisplay();
}

<span class="comment">// --------------------------------------------------------------- keyboard ---</span>
<span class="keywordtype">void</span> keyboard( <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> key, <span class="keywordtype">int</span> x, <span class="keywordtype">int</span> y )
{
    <span class="keywordflow">if</span> ( key == 27 )
    {
        exit( 1 );
    }
}


<span class="comment">// ----------------------------------------------------- make_display_lists ---</span>
<span class="keywordtype">void</span>
make_display_lists( <a class="code" href="structtexture__font__t.html" title="Texture font structure.">texture_font_t</a> * <span class="keyword">self</span> )
{
    <span class="keywordtype">size_t</span> i;
    <a class="code" href="structtexture__glyph__t.html" title="A structure that describe a glyph.">texture_glyph_t</a> * glyph;

    <span class="keywordflow">for</span>( i=0; i&lt;<a class="code" href="group__vector.html#ga0103842074bb797fc685b33c0629c05a" title="Returns the number of items.">vector_size</a>(self-&gt;glyphs) ; ++i)
    {
        glyph = *(<a class="code" href="structtexture__glyph__t.html" title="A structure that describe a glyph.">texture_glyph_t</a> **) <a class="code" href="group__vector.html#ga6ed3fefa82526009ff0763191dcd9a93" title="Returns a pointer to the item located at specified index.">vector_get</a>( self-&gt;glyphs, i);
        <span class="keywordtype">int</span> x  = glyph-&gt;<a name="a14"></a><a class="code" href="structtexture__glyph__t.html#a1f267cdba6bd1aff244ff72792ab1a38" title="Glyph&#39;s left bearing expressed in integer pixels.">offset_x</a>;
        <span class="keywordtype">int</span> y  = glyph-&gt;<a name="a15"></a><a class="code" href="structtexture__glyph__t.html#aeacd07f592dfa953f26b2e5c1863a814" title="Glyphs&#39;s top bearing expressed in integer pixels.">offset_y</a>;
        <span class="keywordtype">int</span> w  = glyph-&gt;<a name="a16"></a><a class="code" href="structtexture__glyph__t.html#a51379921bd46b454fc56b7d28381af03" title="Glyph&#39;s width in pixels.">width</a>;
        <span class="keywordtype">int</span> h  = glyph-&gt;<a name="a17"></a><a class="code" href="structtexture__glyph__t.html#a7a0e2fc48006cf6815e5b1e7dae8d386" title="Glyph&#39;s height in pixels.">height</a>;
        <span class="keywordtype">float</span> s0 = glyph-&gt;<a name="a18"></a><a class="code" href="structtexture__glyph__t.html#adcfb6e5a1b583f96c96d87b006667f2b" title="First normalized texture coordinate (x) of top-left corner.">s0</a>;
        <span class="keywordtype">float</span> t0 = glyph-&gt;<a name="a19"></a><a class="code" href="structtexture__glyph__t.html#ab2fec7dd584f5cfaf14c3b8a807d5e70" title="Second normalized texture coordinate (y) of top-left corner.">t0</a>;
        <span class="keywordtype">float</span> s1 = glyph-&gt;<a name="a20"></a><a class="code" href="structtexture__glyph__t.html#a3849b83a8bb51a6fc32ce77b485d9e95" title="First normalized texture coordinate (x) of bottom-right corner.">s1</a>;
        <span class="keywordtype">float</span> t1 = glyph-&gt;<a name="a21"></a><a class="code" href="structtexture__glyph__t.html#aee3ba35a29e1646df9cfaca6c0db3488" title="Second normalized texture coordinate (y) of bottom-right corner.">t1</a>;
        <span class="keywordflow">if</span>( glyph-&gt;<a class="code" href="structtexture__glyph__t.html#ade972fbd816ec6f4dbd95ddd2e03746a" title="Glyph id (used for display lists)">id</a> )
        {
            glDeleteLists( glyph-&gt;<a class="code" href="structtexture__glyph__t.html#ade972fbd816ec6f4dbd95ddd2e03746a" title="Glyph id (used for display lists)">id</a>, 1 );
        }
        glyph-&gt;<a class="code" href="structtexture__glyph__t.html#ade972fbd816ec6f4dbd95ddd2e03746a" title="Glyph id (used for display lists)">id</a> = glGenLists( 1 );
        glNewList( glyph-&gt;<a class="code" href="structtexture__glyph__t.html#ade972fbd816ec6f4dbd95ddd2e03746a" title="Glyph id (used for display lists)">id</a>,GL_COMPILE );
        glBegin( GL_TRIANGLES );
        glTexCoord2f( s0, t0 ); glVertex2i( x,   y   );
        glTexCoord2f( s0, t1 ); glVertex2i( x,   y-h );
        glTexCoord2f( s1, t1 ); glVertex2i( x+w, y-h );
        glTexCoord2f( s0, t0 ); glVertex2i( x,   y   );
        glTexCoord2f( s1, t1 ); glVertex2i( x+w, y-h );
        glTexCoord2f( s1, t0 ); glVertex2i( x+w, y   );
        glEnd();
        glEndList();
    }
};


<span class="comment">// ------------------------------------------------------------------- main ---</span>
<span class="keywordtype">int</span> main( <span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv )
{
    <span class="keywordtype">size_t</span> i;

    glutInit( &amp;argc, argv );
    glutInitWindowSize( 800, 400 );
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
    glutCreateWindow( <span class="stringliteral">&quot;Freetype OpenGL / display lists&quot;</span> );
    glutReshapeFunc( reshape );
    glutDisplayFunc( display );
    glutKeyboardFunc( keyboard );

    <span class="comment">// Build fonts and corresponding display lists</span>
    fonts = <a name="a22"></a><a class="code" href="group__vector.html#ga9ab13f896bb29debbbf8175e75751ea5" title="Creates a new empty vector.">vector_new</a>( <span class="keyword">sizeof</span>(<a class="code" href="structtexture__font__t.html" title="Texture font structure.">texture_font_t</a>) );
    atlas = <a name="a23"></a><a class="code" href="group__texture-atlas.html#ga7769be70f630e0a8a8b320525a07382d" title="Creates a new empty texture atlas.">texture_atlas_new</a>( 512, 512, 1 );
    <span class="keywordflow">for</span>( i=7; i &lt; 27; ++i)
    {
        <a class="code" href="structtexture__font__t.html" title="Texture font structure.">texture_font_t</a> * font = <a name="a24"></a><a class="code" href="group__texture-font.html#ga904424e7b0e2be14b694599b5c483e64" title="This function creates a new texture font from given filename and size.">texture_font_new</a>( atlas, filename, i );
        <a name="a25"></a><a class="code" href="group__texture-font.html#ga912b65dd3d45ced38640cdfbecbb51c5" title="Request the loading of several glyphs at once.">texture_font_load_glyphs</a>( font, text );
        make_display_lists( font );
        <a name="a26"></a><a class="code" href="group__vector.html#ga0934c3049233d3688b7fa74e23536bbf" title="Appends given item to the end of the vector.">vector_push_back</a>( fonts, font );
        free( font ); <span class="comment">// We&#39;re only freeing the local copy of the font</span>
    }
    glutMainLoop( );
    <a name="a27"></a><a class="code" href="group__texture-atlas.html#gac3fc1f3aaa1a18945bd1883aa18fb7ef" title="Deletes a texture atlas.">texture_atlas_delete</a>( atlas );
    <span class="keywordflow">return</span> 0;
}
</pre></div> </div><!-- contents -->
</div>
</body>
</html>
